<template>
  <div id="app">
    <router-view />
  </div>
</template>

<script>
import store from './store'
import router from './router'
export default {
  name: 'App',
  data() {
    return {
      lockReconnect: false, // 是否真正建立连接
      timeout: 58 * 1000, // 58秒一次心跳
      timeoutObj: null, // 心跳心跳倒计时
      serverTimeoutObj: null, // 心跳倒计时
      timeoutnum: null // 断开 重连倒计时
    }
  },
  destroyed() {
    this.$eventBus.ws.close() // 离开路由之后断开websocket连接
  },
  created() {
    this.initWebSocket()
    this.initRouters()
  },
  mounted() {},
  methods: {
    async initRouters() {
      const noFoundRouter = { path: '*', redirect: '/404', hidden: true }
      if (!store.backendRouterInit) {
        const accessRoutes = await store.dispatch('backendRouter/generateRoutes', ['admin'])
        // 最后添加404路由
        accessRoutes.push(noFoundRouter)
        router.options.routes.push(...accessRoutes)
        router.addRoutes(accessRoutes)
        store.backendRouterInit = true
      }
    },
    initWebSocket() {
      // 初始化weosocket
      const wsuri =
        process.env.VUE_APP_BASE_API.replace('http', 'ws') + 'websocket'
      this.$eventBus.ws = new WebSocket(wsuri)
      // 客户端接收服务端数据时触发
      this.$eventBus.ws.onmessage = this.websocketonmessage
      // 连接建立时触发
      this.$eventBus.ws.onopen = this.websocketonopen
      // 通信发生错误时触发
      this.$eventBus.ws.onerror = this.websocketonerror
      // 连接关闭时触发
      this.$eventBus.ws.onclose = this.websocketclose
    },
    // 连接建立时触发
    websocketonopen(msg) {
      console.log('---onopen---', msg)
      // 开启心跳
      this.start()
      // 连接建立之后执行send方法发送数据
      // let actions = {"room":"007854ce7b93476487c7ca8826d17eba","info":"1121212"};
      // this.websocketsend(JSON.stringify(actions));
    },
    // 通信发生错误时触发
    websocketonerror() {
      console.log('出现错误')
      this.reconnect()
    },
    // 客户端接收服务端数据时触发
    websocketonmessage(e) {
      // 收到服务器信息，心跳重置
      this.reset()
      const data = JSON.parse(e.data)
      const event_type = data.msg_type
      const handlers = this.$eventBus.eventBus[event_type]
      console.log('--message---', e)
      if (handlers === undefined) {
        console.log(`事件：${event_type}未被订阅`)
      } else {
        handlers.forEach(func => {
          func(data.msg_data)
        })
      }
    },
    websocketsend(Data) {
      // 数据发送
      this.$eventBus.ws.send(Data)
    },
    // 连接关闭时触发
    websocketclose(e) {
      // 关闭
      console.log('断开连接', e)
      // 重连
      this.reconnect()
    },
    reconnect() {
      // 重新连接
      var that = this
      if (that.lockReconnect) {
        return
      }
      that.lockReconnect = true
      // 没连接上会一直重连，设置延迟避免请求过多
      that.timeoutnum && clearTimeout(that.timeoutnum)
      that.timeoutnum = setTimeout(function() {
        // 新连接
        that.initWebSocket()
        that.lockReconnect = false
      }, 5000)
    },
    reset() {
      // 重置心跳
      var that = this
      // 清除时间
      clearTimeout(that.timeoutObj)
      clearTimeout(that.serverTimeoutObj)
    },
    start() {
      // 开启心跳
      console.log('开启心跳')
      var self = this
      self.timeoutObj && clearTimeout(self.timeoutObj)
      self.serverTimeoutObj && clearTimeout(self.serverTimeoutObj)
      self.timeoutObj = setTimeout(function() {
        // 这里发送一个心跳，后端收到后，返回一个心跳消息，
        if (self.$eventBus.ws.readyState === 1) {
          // 如果连接正常
          // self.ws.send("heartCheck"); //这里可以自己跟后端约定
        } else {
          // 否则重连
          self.reconnect()
        }
        self.serverTimeoutObj = setTimeout(function() {
          // 超时关闭
          self.$eventBus.ws.close()
        }, self.timeout)
      }, self.timeout)
    }
  }
}
</script>
